package cn.shadow.module.snake;

import cn.shadow.module.chess.message.chnChess.frame.ChessFactory;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Array;

public class Snake extends Stage {
    private TextureRegion head;
    private TextureRegion tail;
    private TextureRegion[] bodes;
    private int initLen;
    private SnakeNode headNode;
    private boolean isOver;
    private Music bgMusic;
    private Shoot shoot;
    private float mapX;
    private float mapY;

    public Snake(int initLen) {
        Texture headTexture = new Texture(Gdx.files.internal("image/head.png"));
        Texture tailTexture = new Texture(Gdx.files.internal("image/bullet.png"));
        Texture texture = new Texture(Gdx.files.internal("image/food.png"));
        bgMusic = Gdx.audio.newMusic(Gdx.files.internal("sound/pa.mp3"));
        this.initLen = initLen;
        this.head = new TextureRegion(headTexture, 0, 0, headTexture.getWidth(), headTexture.getHeight());
        this.tail = new TextureRegion(tailTexture, 0, 0, tailTexture.getWidth(), tailTexture.getHeight());
        this.bodes = createBodes(texture);
        this.shoot = new Shoot();
        Gdx.input.setInputProcessor(this);
        initSnake();
        initMusic();
    }

    public float getMapX() {
        return mapX;
    }

    public void setMapX(float mapX) {
        this.mapX = mapX;
    }

    public float getMapY() {
        return mapY;
    }

    public void setMapY(float mapY) {
        this.mapY = mapY;
    }

    public void initMusic() {
        bgMusic.setVolume(0.5f);
        bgMusic.play();
    }

    private TextureRegion[] createBodes(Texture texture) {
        int count = 3;
        int with = texture.getWidth() / 3;
        TextureRegion[] bodes = new TextureRegion[count];
        for (int i = 0; i < count; i++) {
            bodes[i] = new TextureRegion(texture, with * i, 0, with, texture.getHeight());
        }
        return bodes;
    }

    private TextureRegion randBodes() {
        int length = bodes.length;
        int index = (int) (Math.random() * length);
        return bodes[index];
    }

    /**
     * 初始化
     */
    public void initSnake() {
        SnakeNode headNode = new SnakeNode(SnakeNode.NodeType.HEAD, head);
        this.headNode = headNode;
        headNode.setHeadNode(headNode);
        float headX = getWidth() / 2;
        float heady = getHeight() / 2;
        headNode.setPosition(headX, heady); //头部设置初始值
        addActor(headNode);
        float radius = headNode.getBodyX();  //间隔
        SnakeNode temp = headNode;
        for (int i = 0; i < initLen; i++) {
            SnakeNode bodyNode = new SnakeNode(SnakeNode.NodeType.BODY, randBodes());
            bodyNode.setPreNode(temp);
            bodyNode.setHeadNode(headNode);
            temp = bodyNode;
            float bodyX = headX - ((i + 1) * radius);
            bodyNode.setPosition(bodyX, heady);
            addActor(bodyNode);
        }
        Array<Actor> actors = getActors();
        Actor tail = actors.get(actors.size - 1);
        SnakeNode tailNode = (SnakeNode) tail;
        tailNode.setDisplay(this.tail);
        this.addListener(new MyInputListener());
//        this.addListener(new MyClickListener());
    }

    @Override
    public void act() {
        super.act();
        if (headNode.isPause()) {
            bgMusic.pause();
            return;
        } else {
            if (!bgMusic.isPlaying()) {
                bgMusic.play();
            }
        }
        if (isOver) {
            initSnake();
            isOver = false;
        }
        if (isOver()) {
            this.isOver = true;
            doWhenOver();
        }
        shootDisPlay();
    }

    public void shootDisPlay() {
        this.shoot.act();
        this.shoot.draw();
        this.shoot.checkHit();
    }

    public Actor shoot() {
        Bullet shoot = this.shoot.shoot(headNode.getX(), headNode.getY(), headNode.getDirection());
        int index = getActors().size - 2;
        if (index == 0) {
            index = 1;
        }
        SnakeNode snakeNode = (SnakeNode) (getActors().get(index));
        shoot.setBullet(snakeNode.getDisplay());
        if (getActors().size > 2) {
            Actor last = this.getActors().peek();
            if (last instanceof SnakeNode) {
                SnakeNode preNode = ((SnakeNode) last).getPreNode(); //倒数第二个
                float x = preNode.getX();
                float y = preNode.getY();
                SnakeNode prePreNode = preNode.getPreNode(); //倒数第三个
                ((SnakeNode) last).setPreNode(prePreNode);
                last.setPosition(x, y);
                getRoot().removeActor(preNode);
            }
        }
        return shoot;
    }

    public Shoot getShoot() {
        return shoot;
    }

    public void setShoot(Shoot shoot) {
        this.shoot = shoot;
    }

    public void setOver(boolean over) {
        isOver = over;
    }

    /**
     * 游戏结束时
     */
    private void doWhenOver() {
        Group root = getRoot();
        root.clear();
    }

    /**
     * 变长
     */
    public void growUp(TextureRegion region) {
        Array<Actor> actors = getActors();
        Group root = getRoot();
        int tailIndex = actors.size - 1;
        Actor actor = actors.get(tailIndex);
        SnakeNode OldTail = (SnakeNode) actor;
        OldTail.setDisplay(region);
        SnakeNode newTail = new SnakeNode(SnakeNode.NodeType.BODY, this.tail);
        newTail.setPosition(OldTail.getX(), OldTail.getY());
        newTail.setPreNode(OldTail);
        newTail.setHeadNode(headNode);
        root.addActor(newTail);
    }

    public void growUp() {
        growUp(randBodes());
    }

    public boolean isOver() {
        return headNode.overRanged(this.getMapX(), this.getMapY());
    }

}
